home *** CD-ROM | disk | FTP | other *** search
/ Aminet 1 (Walnut Creek) / Aminet - June 1993 [Walnut Creek].iso / aminet / dev / lang / bcpl4amiga.lha / bcpl / icint.doc < prev    next >
Text File  |  1988-03-23  |  22KB  |  711 lines

  1.  INTCODE - An Interpretive Machine
  2.  ---------------------------------
  3.  
  4.  Code for BCPL
  5.  -------------
  6.  
  7.  by
  8.  
  9.  M. Richards
  10.  
  11.  
  12.  
  13.  
  14.  ABSTRACT
  15.  
  16.  
  17.       INTCODE is a very simple machine code with an
  18.       equally simple assembly language.  An assembler
  19.       and interpreter for it is easy to write and may
  20.       be used for the initial step of bootstrapping
  21.       BCPL onto a new machine.
  22.  
  23.  
  24.  
  25.  
  26.  
  27.  December 1972 (revised August 1975)       The Computer Laboratory
  28.  -------------                                Corn Exchange Street
  29.                                                  Cambridge CB2 3QG
  30.  
  31.  
  32.  
  33.  
  34.        INTCODE - An Interpretive Machine Code for BCPL
  35.        -----------------------------------------------
  36.  
  37.  
  38.  INTCODE is an interpretive machine code which was designed to
  39.  ease the initial bootstrapping of BCPL ¡1, 2, 3¢ onto a new machine.
  40.  The main advantage of INTCODE is that it is compact and its assembler
  41.  and interpreter are both easy to implement.  The assembler and
  42.  interpreter are together about 4 to 6 times smaller than a typical
  43.  BCPL codegenerator from OCODE to assembly language and can be
  44.  implemented in machine code in about 2 days.  The INTCODE form of
  45.  the entire BCPL compiler from BCPL to INTCODE takes about 1000 lines
  46.  of 72 characters composed as follows:
  47.  
  48.       Syntax analyser     BCPL to AE TREE     400 lines
  49.       Translation phase   AE TREE to OCODE    400 lines
  50.       Code Generator      OCODE to INTCODE    200 lines
  51.  
  52.  Even though with INTCODE one loses a factor of about 10 to one in
  53.  execution speed, it is still a useful tool for the initial
  54.  implementation of BCPL on a new machine since it allows the first
  55.  production codegenerator to be written directly in BCPL.
  56.  
  57.  The INTCODE Machine
  58.  -------------------
  59.  
  60.  The INTCODE machine has a store consisting of equal sized
  61.  locations addressed by consecutive integers.  The word size is
  62.  implementation dependent but should normally be at least 24 bits
  63.  in order to hold all the fields of an instruction.  On a 16 bit
  64.  machine, one can use 16 bit and 32 bit instructions; the choice
  65.  between short and long instructions being made by the INTCODE
  66.  assembler.
  67.  
  68.  The central registers of the machine are as follows:
  69.  
  70.  A,B:     The Accumulator and Auxiliary Accumulator.
  71.  
  72.  C:       The Control Register giving the location of
  73.           next instruction to be executed.
  74.  
  75.  D:       The Address register used to hold the effective address
  76.           of an instruction.
  77.  
  78.  P:       A pointer used to address the local work area and
  79.           function arguments.
  80.  
  81.  G:       A pointer used to address the global vector.
  82.  
  83.  
  84.  The format of an instruction is composed of five fields
  85.  as follows:
  86.  
  87.  
  88.  Function Part:      This is a three bit field specifying one of the
  89.                      eight possible machine functions described below.
  90.  
  91.  Address field:      This is a field specifying a positive integer which
  92.                      is the initial value of D.  The address field should
  93.                      contain at least 14 or 15 bits.
  94.  
  95.  P bit:              A single bit to specify whether P is to be added
  96.                      into D at the second stage of address evaluation.
  97.  
  98.  G bit:              A single bit to specify whether G is to be added
  99.                      into D at the third stage of address evaluation.
  100.  
  101.  I bit:              This is the indirection bit.  If it is a one then D
  102.                      is replaced by the contents of the location addressed
  103.                      by D at the last stage of address evaluation.
  104.  
  105.  
  106.  The effective address is evaluated in the same way for every
  107.  instruction independent of the particular machine function specified.
  108.  
  109.  
  110.  The eight machine functions are as follows:
  111.  
  112.  
  113.  0)     Load                                           Mnemonic L
  114.  
  115.         Load the effective address into the accumulator A saving
  116.         its previous value in B.
  117.  
  118.         B := A;     A := D
  119.  
  120.  1)     Store                                          Mnemonic S
  121.  
  122.         Store the accumulator A into the location addressed by D.
  123.  
  124.         Location (D) := A
  125.  
  126.  2)     Add                                            Mnemonic S
  127.  
  128.         Add the effective address D into the accumulator A.
  129.  
  130.         A := A + D
  131.  
  132.  3)     Jump                                           Mnemonic J
  133.  
  134.         Cause a transfer of control by setting the control register C
  135.         to the effective address D.
  136.  
  137.         C := D
  138.  
  139.  4)     Jump if True                                   Mnemonic T
  140.  
  141.         This is a conditional transfer which sets the control register C
  142.         to D if the Accumulator A is non-zero.
  143.  
  144.         IF A^= O DO C := D
  145.  
  146.  5)     Jump if False                                  Mnemonic F
  147.  
  148.         This is a conditional transfer which sets the control register C
  149.         to D if the accumulator A is zero.
  150.  
  151.         IF A=0 DO C := D
  152.  
  153.  6)     Call a function                                Mnemonic K
  154.  
  155.         Cause a recursive function call to take place.  The current
  156.         stack frame size is specified by D and the function entry point
  157.         is given in A.  The first two cells of the new stack frame are set
  158.         to hold the return link information.
  159.  
  160.         D := P + D
  161.  
  162.         Location(D), Location(D+1) := P, C
  163.  
  164.         P,C := D,A
  165.  
  166.  7)     Execute operation                              Mnemonic X
  167.  
  168.         This instruction allows auxiliary operations to be executed.
  169.         The operation is specified by the value of D which should be a
  170.         small integer.  These operations are mainly of an arithmetic or
  171.         logical nature working on the accumulators A and B, and are
  172.         specified as follows:
  173.  
  174.       X1: A := Location (A)
  175.  
  176.       X2: A := -A
  177.  
  178.       X3: A := NOT A
  179.  
  180.       X4: This causes a return from the current function or routine;
  181.           by convention the result fo a function is left in A.
  182.  
  183.           C := Location(P + 1)
  184.  
  185.           P := Location(P)
  186.  
  187.       X5: A := B * A
  188.  
  189.       X6: A := B / A
  190.  
  191.       X7: A := B REM A
  192.  
  193.       X8: A := B + A
  194.  
  195.       X9: A := B - A
  196.  
  197.       X10: A := B = A
  198.  
  199.       X11: A := B ^= A
  200.  
  201.       X12: A := B < A
  202.  
  203.       X13: A := B >= A
  204.  
  205.       X14: A := B > A
  206.  
  207.       X15: A := B <= A
  208.  
  209.       X16: A := B LSHIFT A     // vacated positions
  210.  
  211.       X17: A := B RSHIFT A     // are filled with zeroes
  212.  
  213.       X18: A := B LOGAND A
  214.  
  215.       X19: A := B LOGOR A
  216.  
  217.       X20: A := B NEQV A
  218.  
  219.       X21: A := B EQV A
  220.  
  221.       X22: FINISH
  222.       X23: Switch on the value of A using data in the location
  223.            addressed by C, C+1 etc.
  224.  
  225.            B, D := Location(C), Location(C + 1)
  226.  
  227.            UNTIL B = 0 DO
  228.  
  229.                 $( B, C := B - 1, C + 2
  230.  
  231.                      IF A=Location(C) DO
  232.  
  233.                           $( D := Location(C + 1)
  234.  
  235.                                BREAK $)       $)
  236.  
  237.            C := D
  238.  
  239.       X24:These are implementation dependent instructions
  240.       X25: for input/output operations and other special
  241.            functions.  See the listing  of the INTCODE interpreter
  242.            in the appendix.
  243.  
  244.  
  245.  INTCODE Assembly Language
  246.  _________________________
  247.  
  248.  The assembly language for INTCODE has been designed to be
  249.  compact and simple to assemble, but care has also been taken so
  250.  that it can be read and modified with reasonable ease by a
  251.  programmer.  The text of the assembly language is composed of
  252.  letters, digits, spaces, newlines and the characters '/' and
  253.  dollar '$'.
  254.  
  255.  Slash is used as a continuation symbol;  it is skipped and
  256.  the remaining characters of the line up to and including the
  257.  next newline character are ignored.  Its main purpose is to
  258.  simplify the efficient use of cards as a medium for transferring
  259.  INTCODE programs.
  260.  
  261.  Dollar marks the entry point of a function or routine and is
  262.  otherwise ignorable.  Its sole purpose is to help the implementer
  263.  find his way around compiled code.
  264.  
  265.  The assembly form of an instruction consists of the mnemonic
  266.  letter for the machine function, optionally followed by 'I' if
  267.  indirection is specified, optionally followed by 'P' or 'G' if
  268.  P or G modifications are specified, followed by the address which
  269.  is either a decimal integer or an assembly parameter which appears
  270.  as 'L' followed by a decimal integer.  Assembly parameters are
  271.  numbered in the range 1 to 500 and are used to label points in the
  272.  program.  A number not preceded by a letter is interpreted as a
  273.  label and causes the specified assembly parameter to be set to the
  274.  address of the next location to be loaded.
  275.  
  276.  The mnemonics for the machine functions are L, S, A, J, T, F, K
  277.  and X as described in the previous section.
  278.  
  279.  Data may be assembled by a statement consisting of 'D' followed
  280.  by a signed decimal integer for constant values or 'DL' followed by
  281.  an assembly parameter number for pointers.  Characters may be packed
  282.  and assembled using character statements of the form 'C' followed by
  283.  the integer code for the character.  The character size and number
  284.  of characters per word are machine dependent and it is left to the
  285.  assembler to pack character strings appropriately.  A label,
  286.  instruction or data statement will cause the latest character string
  287.  to be padded with zeros so that the loading pointer points to the
  288.  start of a full word.
  289.  
  290.  It is possible to initialise global variables during assembly,
  291.  using a directive of the form 'G' followed by a global number,
  292.  followed by 'L' and an assembly parameter number.  Thus G36L73 will
  293.  cause global 36 of the INTCODE machine to be set to the value of
  294.  assembly parameter number 73.
  295.  
  296.  'Z' is used to mark the end of each segment of code.  Its effect
  297.  is to unset all the numerical parameters.
  298.  
  299.  
  300.  Conclusion
  301.  ----------
  302.  
  303.  The effectiveness of INTCODE lies mainly in its simplicity making
  304.  it easy to understand and implement; however, it is also compact and
  305.  even with a simple non-optimising code generator the compiled code is
  306.  smaller than straightforward machine code for most machines by a factor
  307.  of nearly two to one.
  308.  
  309.  Example
  310.  -------
  311.  
  312.  The following BCPL program:
  313.  
  314.  
  315.  GLOBAL $( START:1; WRITEF:76 $)
  316.  
  317.  LET START () BE $(1
  318.  
  319.  LET F(N) = N=0 -> 1, N*F(N-1)
  320.  
  321.  FOR I = 1 TO 10 DO WRITEF("F(%N), = %N*N", I, F(I))
  322.  
  323.  FINISH $)1
  324.  
  325.  compiles into the following INTCODE:
  326.  
  327.  $ 1 JL4
  328.  $ 2 LO LIP2 X10 FL6 L1 SP3 JL5 6 LIP2 L1 X9 SP5 LIL3 K3 LIP2 X5 SP3 5 L/
  329.  IP3 X4 4 L1 SP2 J17 8 LI499 SP5 LIP2 SP6 LIP2 SP9 LIL3 K7 SP7 LIG76 K3 /
  330.  LIP2 A1 SP2 7 LIP2 L10 X15 TL8 X22 X22
  331.  3 DL2 499 C11 C70 C40 C37 C78 C41 C32 C61 C32 C37 C78 C10
  332.  GIL1
  333.  Z
  334.  
  335.  
  336.  
  337.  References
  338.  ----------
  339.  
  340.  
  341.  ¡1¢  Richards, M.    BCPL - A tool for Compiler Writing and Sysyems
  342.                       Programming.  SJCC 1969.
  343.  
  344.  ¡2¢  --------        BCPL Programming Manual.  Computer Laboratory,
  345.                       Cambridge 1973.
  346.  
  347.  ¡3¢  --------        The Portability of the BCPL Compiler.
  348.                       Software Practice and Experience, Vol. 1,
  349.                       No. 2 (1971).
  350.  
  351.  
  352.  Appendix - The INTCODE Assembler and Interpreter
  353.  ------------------------------------------------
  354.  
  355.  //  This program is an ASCII INTCODE assembler and interpreter
  356.  //  for a 16 bit EBCDIC machine, hence the need for the ASCII and
  357.  //  EBCDIC tables near the end.  It has been tested on the IBM 370
  358.  //  (a 32 bit EBCDIC machine).
  359.  
  360.  GET "LIBHDR"
  361.  
  362.  GLOBAL $(
  363.  SYSPRINT:100; SOURCE:101
  364.  ETOA:102; ATOE:103
  365.  $)
  366.  
  367.  MANIFEST $(
  368.  FSHIFT=13
  369.  IBIT=#10000; PBIT=#4000; GBIT=#2000; DBIT=#1000
  370.  ABITS=#777
  371.  WORDSIZE=16; BYTESIZE=8
  372.  LIG1=#012001
  373.  K2  =#140002
  374.  X22 =#160026
  375.  $)
  376.  
  377.  GLOBAL $(
  378.  G:110; P:111; CH:112; CYCLECOUNT:113
  379.  LABV:120; CP:121; A:122; B:123; C:124; D:125; W:126 $)
  380.  
  381.  
  382.  LET ASSEMBLE() BE
  383.  $(1   LET V = VEC 500
  384.        LET F = 0
  385.        LABV := V
  386.  
  387.  CLEAR:FOR I = 0 to 500 DO LABV:I := 0
  388.        CP := 0
  389.  
  390.  NEXT: RCH()
  391.  SW:   SWITCHON CH INTO
  392.  
  393.  $(S   DEFAULT: IF CH=ENDSTREAMCH RETURN
  394.                 WRITEF("*NBAD CH %C AT P = %N*N", CH, P)
  395.                 GOTO NEXT
  396.  
  397.        CASE '0' : CASE '1' : CASE '2' : CASE '3' : CASE '4' :
  398.        CASE '5' : CASE '6' : CASE '7' : CASE '8' : CASE '9' :
  399.                 SETLAB(RDN())
  400.                 CP := 0
  401.                 GOTO SW
  402.        CASE '$' : CASE '*S' : CASE '*N' : GOTO NEXT
  403.  
  404.        CASE 'L' : F := 0; ENDCASE
  405.        CASE 'S' : F := 1; ENDCASE
  406.        CASE 'A' : F := 2; ENDCASE
  407.        CASE 'J' : F := 3; ENDCASE
  408.        CASE 'T' : F := 4; ENDCASE
  409.        CASE 'F' : F := 5; ENDCASE
  410.        CASE 'K' : F := 6; ENDCASE
  411.        CASE 'X' : F := 7; ENDCASE
  412.  
  413.        CASE 'C' : RCH(); STC(RDN()); GOTO SW
  414.  
  415.        CASE 'D' : RCH()
  416.                   TEST CH='L'
  417.                     THEN $( RCH()
  418.                             STW(0)
  419.                             LABREF(RDN(), P-1)   $)
  420.                     OR STW(RDN())
  421.                   GOTO SW
  422.  
  423.        CASE 'G' : RCH()
  424.                   A := RDN() + G
  425.                   TEST CH='L' THEN RCH()
  426.                         OR WRITEF("*NBAD CODE AT P = %N*N", P)
  427.                   ]A := 0
  428.                   LABREF(RDN(), A)
  429.                   GOTO SW
  430.  
  431.        CASE 'Z' : FOR I = 0 TO 500 DO
  432.                       IF LABV]I>0 DO WRITEF("L%N UNSET*N", I)
  433.                   GOTO CLEAR $)S
  434.  
  435.        W := F<<FSHIFT
  436.        RCH()
  437.        IF CH='I' DO $( W := W+IBIT; RCH() $)
  438.        IF CH='P' DO $( W := W+PBIT; RCH() $)
  439.        IF CH='G' DO $( W := W+GBIT; RCH() $)
  440.  
  441.        TEST CH='L'
  442.  
  443.          THEN $( RCH()
  444.                  STW(W+DBIT)
  445.                  STW(0)
  446.                  LABREF(RDN(), P-1) $)
  447.  
  448.          OR   $( LET A = RDN()
  449.                  TEST (A&ABITS)=A
  450.                    THEN STW(W+A)
  451.                     OR $( STW(W+DBIT); STW(A) $) $)
  452.  
  453.        GOTO SW $)1
  454.  
  455.  AND STW(W) BE $( ]P := W
  456.                   P, CP := P+1, 0 $)
  457.  
  458.  AND STC(C) BE $( IF CP=0 DO $( STW(0); CP := WORDSIZE $)
  459.                   CP := CP - BYTESIZE
  460.                   ](P-1) := ](P-1) + (C<<CP) $)
  461.  
  462.  AND RCH() BE $(1 CH := RDCH()
  463.                   UNLESS CH='/' RETURN
  464.                   UNTIL CH='*N' DO CH := RDCH() $)1 REPEAT
  465.  
  466.  AND RDN() = VALOF
  467.      $( LET A, B = 0, FALSE
  468.         IF CH='-' DO $( B := TRUE; RCH() $)
  469.         WHILE '0'<=CH<='9' DO $( A := 10*A + CH - '0'; RCH() $)
  470.         IF B DO A := -A
  471.         RESULTIS A $)
  472.  
  473.  AND SETLAB(N) BE
  474.       $( LET K = LABV]N
  475.          IF K<0 DO WRITEF("L%N ALREADY SET TO %N AT P = %N*N",N,-K,P)
  476.          WHILE K>0 DO $( LET N = ]K
  477.                              ]K := P
  478.                              K := N $)
  479.          LABV]N := -P $)
  480.  
  481.  AND LABREF(N, A) BE
  482.      $( LET K = LABV]N
  483.         TEST K<0 THEN K := -K OR LABV]N := A
  484.         ]A := ]A + K $)
  485.  
  486.  AND INTERPRET() = VALOF
  487.  $(1
  488.  
  489.  FETCH: CYCLECOUNT := CYCLECOUNT + 1
  490.         W := ]C
  491.         C := C + 1
  492.  
  493.         TEST (W&DBIT)=0
  494.           THEN D := W&ABITS
  495.           OR $( D := ]C; C := C + 1 $)
  496.  
  497.         IF (W & PBIT) NE 0 DO D := D + P
  498.         IF (W & GBIT) NE 0 DO D:= D + G
  499.         IF (W & IBIT) NE 0 DO D := ]D
  500.  
  501.         SWITCHON W>>FSHIFT INTO
  502.  
  503.     $(  ERROR:
  504.         DEFAULT: SELECTOUTPUT(SYSPRINT)
  505.                  WRITEF("*NINTCODE ERROR AT C = %N*N", C-1)
  506.                  RESULTIS -1
  507.  
  508.         CASE 0: B := A; A := D; GOTO FETCH
  509.  
  510.         CASE 1: ]D := A; GOTO FETCH
  511.  
  512.         CASE 2: A := A + D; GOTO FETCH
  513.  
  514.         CASE 3: C := D; GOTO FETCH
  515.  
  516.         CASE 4: A := NOT A
  517.  
  518.         CASE 5: UNLESS A DO C := D; GOTO FETCH
  519.  
  520.         CASE 6: D := P + D
  521.                 D]0, D]1 := P, C
  522.                 P, C := D, A
  523.                 GOTO FETCH
  524.  
  525.         CASE 7: SWITCHON D INTO
  526.  
  527.         $(  DEFAULT: GOTO ERROR
  528.  
  529.             CASE 1:  A := ]A; GOTO FETCH
  530.             CASE 2:  A := -A; GOTO FETCH
  531.             CASE 3:  A := NOT A; GOTO FETCH
  532.             CASE 4:  C := P]1
  533.                      P := P]0
  534.                      GOTO FETCH
  535.             CASE 5:  A := B * A; GOTO FETCH
  536.             CASE 6:  A := B / A; GOTO FETCH
  537.             CASE 7:  A := B REM A; GOTO FETCH
  538.             CASE 8:  A := B + A; GOTO FETCH
  539.             CASE 9:  A := B - A; GOTO FETCH
  540.             CASE 10: A := B = A; GOTO FETCH
  541.             CASE 11: A := B NE A; GOTO FETCH
  542.             CASE 12: A := B < A; GOTO FETCH
  543.             CASE 13: A := B >= A; GOTO FETCH
  544.             CASE 14: A := B > A; GOTO FETCH
  545.             CASE 15: A := B <= A; GOTO FETCH
  546.             CASE 16: A := B << A; GOTO FETCH
  547.             CASE 17: A := B >> A; GOTO FETCH
  548.             CASE 18: A := B & A; GOTO FETCH
  549.             CASE 19: A := B LOGOR A; GOTO FETCH
  550.             CASE 20: A := B NEQV A; GOTO FETCH
  551.             CASE 21: A := B EQV A; GOTO FETCH
  552.             CASE 22: RESULTIS 0  // FINISH
  553.             CASE 23: B, D := C]0, C]1   // SWITCHON
  554.                      UNTIL B=0 DO
  555.                      $( B, C := B-1, C+2
  556.                         IF A=C]0 DO
  557.                         $( D := C]1
  558.                            BREAK $) $)
  559.                      C := D
  560.                      GOTO FETCH
  561.  
  562.  // CASES 24 UPWARDS ARE ONLY CALLED FROM THE FOLLOWING
  563.  // HAND WRITTEN INTCODE LIBRARY - ICLIB:
  564.  
  565.  //    11 LIP2 X24 X4 G11L11 /SELECTINPUT
  566.  //    12 LIP2 X25 X4 G12L12 /SELECTOUTPUT
  567.  //    13 X26 X4      G13L13 /RDCH
  568.  //    14 LIP2 X27 X4 G14L14 /WRCH
  569.  //    42 LIP2 X28 X4 G42L42 /FINDINPUT
  570.  //    41 LIP2 X29 X4 G41L41 /FINDOUTPUT
  571.  //    30 LIP2 X30 X4 G30L30 /STOP
  572.  //    31 X31 X4 G31L31 /LEVEL
  573.  //    32 LIP3 LIP2 X32 G32L32 /LONGJUMP
  574.  //    46 X33 X4 G46L46 /ENDREAD
  575.  //    47 X34 X4 G47L47 /ENDWRITE
  576.  //    40 LIP3 LIP2 X35 G40L40 /APTOVEC
  577.  //    85 LIP3 LIP2 X36 X4 G85L85 /GETBYTE
  578.  //    86 LIP3 LIP2 X37 X4 G86L86 /PUTBYTE
  579.  //    Z
  580.  
  581.  
  582.             CASE 24: SELECTINPUT(A); GOTO FETCH
  583.             CASE 25: SELECTOUTPUT(A); GOTO FETCH
  584.             CASE 26: A := ETOA]RDCH(); GOTO FETCH
  585.             CASE 27: WRCH(ATOE]A); GOTO FETCH
  586.             CASE 28: A := FINDINPUT(STRING370(A)); GOTO FETCH
  587.             CASE 29: A := FINDOUTPUT(STRING370(A)); GOTO FETCH
  588.             CASE 30: RESULTIS A;  // STOP(A)
  589.             CASE 31: A := P]0; GOTO FETCH  // USED IN LEVEL()
  590.             CASE 32: P, C := A, B;         // USED IN LONGJUMP(P,L)
  591.                      GOTO FETCH
  592.             CASE 33: ENDREAD(); GOTO FETCH
  593.             CASE 34: ENDWRITE(); GOTO FETCH
  594.             CASE 35: D := P+B+1            // USED IN APTOVEC(F, N)
  595.                      D]0, D]1, D]2, D]3 := P]0, P]1, P, B
  596.                      P, C := D, A
  597.                      GOTO FETCH
  598.             CASE 36: A := ICGETBYTE(A, B)  // GETBYTE(S, I)
  599.                      GOTO FETCH
  600.             CASE 37: ICPUTBYTE(A, B, P]4)  // PUTBYTE(S, I, CH)
  601.                      GOTO FETCH
  602.        $)  $)  $)1
  603.  
  604.  AND STRINGTO370(S) = VALOF
  605.       $( LET T = TABLE 0,0,0,0,0,0,0,0
  606.  
  607.          PUTBYTE(T, 0, ICGETBYTE(S, 0))
  608.          FOR I = 1 TO ICGETBYTE(S, 0) DO
  609.                     PUTBYTE(T,I,ATOE]ICGETBYTE(S,I))
  610.  
  611.          RESULTIS T  $)
  612.  
  613.  AND ICGETBYTE(S, I) = VALOF
  614.       $( LET W = S](I/2)
  615.          IF (I&1)=0 DO W := W>>8
  616.          RESULTIS W&255  $)
  617.  
  618.  AND ICPUTBYTE(S, I, CH) BE
  619.       $( LET P= @S](I/2)
  620.          LET W = ]P
  621.          TEST (I&1)=0 THEN ]P := Wÿ LOGOR CH<<8
  622.                       OR   ]P := W＀ LOGOR CH    $)
  623.  
  624.  LET START(PARM) BE
  625.  $(1
  626.  
  627.  LET PROGVEC = VEC 20000
  628.  LET GLOBVEC = VEC 400
  629.  
  630.  G, P := GLOBVEC, PROGVEC
  631.  
  632.  SYSPRINT := FINDOUTPUT("SYSPRINT")
  633.  SELECTOUTPUT(SYSPRINT)
  634.  
  635.  WRITES("INTCODE SYSTEM ENTERED*N")
  636.  
  637.  SOURCE := FINDINPUT("INTIN")
  638.  SELECTINPUT(SOURCE)
  639.  ASSEMBLE()
  640.  SOURCE := FINDINPUT("SYSIN")
  641.  UNLESS SOURCE=0 DO SELECTINPUT(SOURCE)
  642.  
  643.  WRITEF("*NPROGRAM SIZE = %N*N", P-PROGVEC)
  644.  
  645.  
  646.  OTOE := 1+TABLE -1,
  647.            0,  0,  0,  0,  0,  0,  0,  0,  // ASCII TO EBCDIC
  648.            0,  5, 21,  0, 12,  0,  0,  0,  // '*T' '*N' '*P'
  649.            0,  0,  0,  0,  0,  0,  0,  0,
  650.            0,  0,  0,  0,  0,  0,  0,  0,
  651.  
  652.           64, 90,127,123, 91,108, 80,125,  // '*S' ] " # $ % & '
  653.           77, 93, 92, 78,107, 96, 75, 97,  //   (  ) * + , - . /
  654.          240,241,242,243,244,245,246,247,  //   0  1 2 3 4 5 6 7
  655.          248,249,122, 94, 76,126,110,111,  //   8  9 : ; < = > ?
  656.          124,193,194,195,196,197,198,199,  //   @  A B C D E F G
  657.          200,201,209,210,211,212,213,214,  //   H  I J K L M N O
  658.          215,216,217,226,227,228,229,230,  //   P  Q R S T U V W
  659.          231,232,233, 66, 98, 67,101,102,  //   X  Y Z ¡ ² ¢ µ ¶
  660.           64,129,130,131,132,133,134,135,  //      a b c d e f g
  661.          136,137,145,146,147,148,149,150,  //   h  i j k l m n o
  662.          151,152,153,162,163,164,165,166,  //   p  q r s t u v w
  663.          167,168,169, 64, 79, 64, 95,255  //    x  y z   !   ^
  664.  
  665.  
  666.  ETOA := 1+TABLE -1,
  667.        0,   0,   0,   0,   0, #11,   0,   0,
  668.        0,   0,   0, #13, #14, #15,   0,   0,
  669.        0,   0,   0,   0,   0, #12,   0,   0,
  670.        0,   0,   0,   0,   0,   0,   0,   0,
  671.        0,   0,   0,   0,   0, #12,   0,   0,
  672.        0,   0,   0,   0,   0,   0,   0,   0,
  673.        0,   0,   0,   0,   0,   0,   0,   0,
  674.        0,   0,   0,   0,   0,   0,   0,   0,
  675.      #40,   0,#133,#135,   0,   0,   0,   0,
  676.        0,   0,   0, #56, #74, #50, #53,#174,
  677.      #46,   0,   0,   0,   0,   0,   0,   0,
  678.        0,   0, #41, #44, #52, #51, #73,#176,
  679.      #55, #57,#134,   0,   0,#136,#137,   0,
  680.        0,   0,   0, #54, #45,#140, #76, #77,
  681.        0,   0,   0,   0,   0,   0,   0,   0,
  682.        0,   0, #72, #43,#100, #47, #75, #42,
  683.        0,#141,#142,#143,#144,#145,#146,#147,
  684.     #150,#151,   0,   0,   0,   0,   0,   0,
  685.        0,#152,#153,#154,#155,#156,#157,#160,
  686.     #161,#162,   0,   0,   0,   0,   0,   0,
  687.        0,   0,#163,#164,#165,#166,#167,#170,
  688.     #171,#172,   0,   0,   0,   0,   0,   0,
  689.        0,   0,   0,   0,   0,   0,   0,   0,
  690.        0,   0,   0,   0,   0,   0,   0,   0,
  691.        0,#101,#102,#103,#104,#105,#106,#107,
  692.     #110,#111,   0,   0,   0,   0,   0,   0,
  693.        0,#112,#113,#114,#115,#116,#117,#120,
  694.     #121,#122,   0,   0,   0,   0,   0,   0,
  695.        0,   0,#123,#124,#125,#126,#127,#130,
  696.     #131,#132,   0,   0,   0,   0,   0,   0,
  697.      #60, #61, #62, #63, #64, #65, #66, #67,
  698.      #70, #71,   0,   0,   0,   0,   0,   0
  699.  
  700.  
  701.  C := TABLE L1G1, K2, X22
  702.  
  703.  CYCLEOUT := 0
  704.  A := INTERPRET()
  705.  
  706.  SELECTOUTPUT(SYSPRINT)
  707.  WRITEF("*N*NEXECUTION CYCLES = %N, CODE = %N*N", CYCLEOUT, A)
  708.  IF A<0 DO MAPSTORE()
  709.  FINISH  $)1
  710.  
  711.